import { isSameVnode } from './util.js';
import { patchVnode } from './patchVnode.js';
import { createElm } from './createElm.js';
/**
 * 更新子节点
 *
 * @param   {[type]}  parentElm  真实DOM节点，父节点
 * @param   {[type]}  oldCh      旧的虚拟节点
 * @param   {[type]}  newCh      新的虚拟节点
 *
 */
function updateChildren (parentElm, oldCh, newCh) {
  console.log(parentElm, oldCh, newCh);

  let oldStartIdx = 0;//旧前指针
  let oldEndIdx = oldCh.length - 1;// 旧后指针
  let newStartIdx = 0;// 新前指针
  let newEndIdx = newCh.length - 1;// 新后指针

  let oldStartVnode = oldCh[0];// 旧前节点
  let oldEndVnode = oldCh[oldEndIdx];// 旧后节点
  let newStartVnode = newCh[0];// 新前节点
  let newEndVnode = newCh[newEndIdx];// 新后节点


  while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
    if (oldStartVnode == undefined) {
      oldStartVnode = oldCh[++oldStartIdx];
    } else if (oldEndVnode == undefined) {
      oldEndVnode = oldCh[--oldEndIdx];
    } else if (newStartVnode == undefined) {
      newStartVnode = newCh[++newStartIdx];
    } else if (newEndVnode == undefined) {
      newEndVnode = newCh[--newEndIdx];
    } else if (isSameVnode(oldStartVnode, newStartVnode)) {
      console.log('命中1');
      /* 1. 旧前节点和新前节点对比 */
      patchVnode(oldStartVnode, newStartVnode);
      if (newStartVnode) newStartVnode.elm = oldStartVnode?.elm;
      oldStartVnode = oldCh[++oldStartIdx];
      newStartVnode = newCh[++newStartIdx];
    } else if (isSameVnode(oldEndVnode, newEndVnode)) {
      console.log('命中2');
      /* 2. 旧后节点和新后节点对比 */
      patchVnode(oldEndVnode, newEndVnode);
      if (newEndVnode) newEndVnode.elm = oldEndVnode?.elm;
      oldEndVnode = oldCh[--oldEndIdx];
      newEndVnode = newCh[--newEndIdx];
    } else if (isSameVnode(oldStartVnode, newEndVnode)) {
      console.log('命中2');
      /* 3. 旧前节点和新后节点对比 */
      patchVnode(oldStartVnode, newEndVnode);
      if (newEndVnode) newEndVnode.elm = oldStartVnode?.elm;
      /* 移动节点，把旧前的节点移动到旧后节点的后面。 */
      parentElm.insertBefore(oldStartVnode.elm, oldEndVnode.elm.nextSibling);
      oldStartVnode = oldCh[++oldStartIdx];
      newEndVnode = newCh[--newEndIdx];
    } else if (isSameVnode(oldEndVnode, newStartVnode)) {
      console.log('命中4');
      /* 4. 旧后节点和新前节点对比 */
      patchVnode(oldEndVnode, newStartVnode);
      if (newStartVnode) newStartVnode.elm = oldEndVnode?.elm;
      /* 移动节点，把旧后的节点移动到旧前节点的前面。 */
      parentElm.insertBefore(oldEndVnode.elm, oldStartVnode.elm);
      oldEndVnode = oldCh[--oldEndIdx];
      newStartVnode = newCh[++newStartIdx];
    } else {
      console.log('命中5');
      /* 5. 循环 */
      /* 创建一个map，存旧虚拟节点的key和i */
      const map = new Map(), newKey = newStartVnode.key;
      for (let i = oldStartIdx; i <= oldEndIdx; i++) {
        console.log(oldCh[i]);
        /* 可能存在oldCh[i]为undefined，因为，命中5后新旧虚拟节点都有数据，会为处理过的虚拟节点设置为undefined */
        if (oldCh[i] !== undefined) {
          map.set(oldCh[i].key, i);
        }
      }
      if (map.has(newKey)) {
        /* 如果找到了，得到需要移动的虚拟节点，移动位置 */
        const index = map.get(newKey);
        const moveElm = oldCh[index];
        patchVnode(moveElm, newStartVnode);
        /* 处理过的节点需要设置为undefined */
        oldCh[index] = undefined;
        parentElm.insertBefore(moveElm.elm, oldStartVnode.elm)
      } else {
        /* 没有找到，是一个新的节点，需要新增节点 */
        parentElm.insertBefore(createElm(newStartVnode), oldStartVnode.elm);
      }
      newStartVnode = newCh[++newStartIdx];
    }
  }

  if (newStartIdx <= newEndIdx) {
    /* 新增情况 */
    console.log('新增');
    const before = newCh[newEndIdx + 1] ? newCh[newEndIdx + 1].elm : null;
    console.log(newStartIdx, newEndIdx);
    for (let i = newStartIdx; i <= newEndIdx; i++) {
      parentElm.insertBefore(createElm(newCh[i]), before);
    }
  } else if (oldStartIdx <= oldEndIdx) {
    /* 删除情况 */
    console.log('删除');
    for (let i = oldStartIdx; i <= oldEndIdx; i++) {
      parentElm.removeChild(oldCh[i].elm);
    }
  }
}

export {
  updateChildren
}